home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 22 / Cream of the Crop 22.iso / os2 / ext2_200.zip / EXT2_SRC.ZIP / 32BITS / EXT2-OS2 / FSD32 / FS32_FSC.C < prev    next >
C/C++ Source or Header  |  1996-09-21  |  21KB  |  582 lines

  1. //
  2. // $Header: D:/32bits/ext2-os2/fsd32/RCS/fs32_fsctl.c,v 1.1 1996/09/21 22:25:12 Willm Exp Willm $
  3. //
  4.  
  5. // 32 bits Linux ext2 file system driver for OS/2 WARP - Allows OS/2 to
  6. // access your Linux ext2fs partitions as normal drive letters.
  7. // Copyright (C) 1995, 1996 Matthieu WILLM
  8. //
  9. // This program is free software; you can redistribute it and/or modify
  10. // it under the terms of the GNU General Public License as published by
  11. // the Free Software Foundation; either version 2 of the License, or
  12. // (at your option) any later version.
  13. //
  14. // This program is distributed in the hope that it will be useful,
  15. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17. // GNU General Public License for more details.
  18. //
  19. // You should have received a copy of the GNU General Public License
  20. // along with this program; if not, write to the Free Software
  21. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22. #ifdef __IBMC__
  23. #pragma strings(readonly)
  24. #endif
  25.  
  26.  
  27. #define INCL_DOS
  28. #define INCL_DOSERRORS
  29. #define INCL_NOPMAPI
  30. #include <os2.h>
  31.  
  32. #include <string.h>
  33.  
  34. #include <os2/types.h>
  35. #include <os2/StackToFlat.h>
  36. #include <linux/fs.h>
  37. #include <os2/os2proto.h>
  38. #include <os2/fsd32.h>
  39. #include <os2/fsh32.h>
  40. #include <os2/DevHlp32.h>
  41. #include <os2/log.h>
  42. #include <os2/trace.h>
  43. #include <os2/errors.h>
  44. #include <os2/files.h>
  45. #include <os2/volume.h>
  46. #include <linux/fs_proto.h>
  47. #include <linux/stat.h>
  48. #include <os2/vfsapi.h>
  49. #include <os2/ifsdbg.h>
  50.  
  51. /*
  52.  * Error messages to return for func. FSCTL_FUNC_NEW_INFO
  53.  */
  54. static struct fsctl_msg ext2_os2_magic   = {sizeof(magic_msg), magic_msg};
  55. static struct fsctl_msg ext2_os2_default = {sizeof(default_msg), default_msg};
  56.  
  57. int fsctl_func_new_info(struct fs32_fsctl_parms *parms) {
  58.     int  rc, rc2;
  59.     char *pParm;
  60.     char *pData;
  61.     unsigned short *pLenParmOut;
  62.     unsigned short *pLenDataOut;
  63.     char lock_1[12];
  64.     char lock_2[12];
  65.     char lock_3[12];
  66.     char lock_4[12];
  67.     unsigned long PgCount;
  68.     short error;
  69.  
  70.     if ((rc = DevHlp32_VirtToLin(parms->pParm, __StackToFlat(&pParm))) == NO_ERROR) {
  71.         if ((rc = DevHlp32_VirtToLin(parms->pData, __StackToFlat(&pData))) == NO_ERROR) {
  72.             if ((rc = DevHlp32_VirtToLin(parms->plenDataOut, __StackToFlat(&pLenDataOut))) == NO_ERROR) {
  73.                 if ((rc = DevHlp32_VirtToLin(parms->plenParmOut, __StackToFlat(&pLenParmOut))) == NO_ERROR) {
  74.  
  75.                     rc = DevHlp32_VMLock(VMDHL_LONG | VMDHL_VERIFY, pParm, sizeof(short), (void *)-1, __StackToFlat(lock_1), __StackToFlat(&PgCount));
  76.                     if ((rc == NO_ERROR) || (rc == ERROR_NOBLOCK)) {
  77.  
  78.                         error = *((short *)pParm);
  79.                         rc = DevHlp32_VMLock(VMDHL_LONG | VMDHL_VERIFY | VMDHL_WRITE, pData, sizeof(struct fsctl_msg), (void *)-1, __StackToFlat(lock_2), __StackToFlat(&PgCount));
  80.                         if ((rc == NO_ERROR) || (rc == ERROR_NOBLOCK)) {
  81.  
  82.                             if (error == NO_ERROR) {
  83.                                 memcpy(pData, &ext2_os2_magic, sizeof(ext2_os2_magic));
  84.                             } else {
  85.                                 memcpy(pData, &ext2_os2_default, sizeof(ext2_os2_default));
  86.                             }
  87.  
  88.                             rc = DevHlp32_VMLock(VMDHL_LONG | VMDHL_VERIFY | VMDHL_WRITE, pLenDataOut, sizeof(short), (void *)-1, __StackToFlat(lock_3), __StackToFlat(&PgCount));
  89.                             if ((rc == NO_ERROR) || (rc == ERROR_NOBLOCK)) {
  90.                                 *pLenDataOut = sizeof(struct fsctl_msg);
  91.  
  92.                                 rc = DevHlp32_VMLock(VMDHL_LONG | VMDHL_VERIFY | VMDHL_WRITE, pLenParmOut, sizeof(short), (void *)-1, __StackToFlat(lock_4), __StackToFlat(&PgCount));
  93.                                 if ((rc == NO_ERROR) || (rc == ERROR_NOBLOCK)) {
  94.                                     *pLenParmOut = 0;
  95.                     rc           = NO_ERROR;
  96.                     if ((rc2 = DevHlp32_VMUnlock(__StackToFlat(lock_4))) == NO_ERROR) {
  97.                                     } else {
  98.                     rc = rc2;
  99.                                     }
  100.                                 }
  101.                 if ((rc2 = DevHlp32_VMUnlock(__StackToFlat(lock_3))) == NO_ERROR) {
  102.                                 } else {
  103.                        rc = rc2;
  104.                                 }
  105.                             }
  106.                      if ((rc2 = DevHlp32_VMUnlock(__StackToFlat(lock_2))) == NO_ERROR) {
  107.                             } else {
  108.                        rc = rc2;
  109.                             }
  110.  
  111.                         }
  112.             if ((rc2 = DevHlp32_VMUnlock(__StackToFlat(lock_1))) == NO_ERROR) {
  113.                         } else {
  114.                    rc = rc2;
  115.                         }
  116.  
  117.             }
  118.                 }
  119.             }
  120.         }
  121.     }
  122.     return rc;
  123. }
  124.  
  125. int ifsdbg_open(struct fs32_fsctl_parms *parms) {
  126.     int rc;
  127.  
  128.     if (BufOpen == 0) {
  129.         BufOpen = 1;
  130.         if (BufPtr == 0) {
  131.             fsh32_semset(&BufSem);
  132.         }
  133.         rc = NO_ERROR;
  134.     } else {
  135.         rc = ERROR_DEVICE_IN_USE;
  136.     }
  137.     return rc;
  138. }
  139.  
  140. int ifsdbg_close(struct fs32_fsctl_parms *parms) {
  141.     int rc;
  142.  
  143.     if (BufOpen == 1) {
  144.         BufOpen = 0;
  145.         rc = NO_ERROR;
  146.     } else {
  147.         rc = ERROR_NOT_READY;
  148.     }
  149.     return rc;
  150. }
  151.  
  152. int ifsdbg_read(struct fs32_fsctl_parms *parms) {
  153.     int  rc, rc2;
  154.     char *pData;
  155.     unsigned short *plenDataOut;
  156.     char lock_1[12];
  157.     char lock_2[12];
  158.     unsigned long PgCount;
  159.  
  160.     if (BufOpen == 1) {
  161.         if ((rc = DevHlp32_VirtToLin(parms->pData, __StackToFlat(&pData))) == NO_ERROR) {
  162.             if ((rc = DevHlp32_VirtToLin(parms->plenDataOut, __StackToFlat(&plenDataOut))) == NO_ERROR) {
  163.                 rc = DevHlp32_VMLock(VMDHL_LONG | VMDHL_VERIFY | VMDHL_WRITE, pData, parms->lenData, (void *)-1, __StackToFlat(lock_1), __StackToFlat(&PgCount));
  164.                 if ((rc == NO_ERROR) || (rc == ERROR_NOBLOCK)) {
  165.                     rc = DevHlp32_VMLock(VMDHL_LONG | VMDHL_VERIFY | VMDHL_WRITE, plenDataOut, sizeof(short), (void *)-1, __StackToFlat(lock_2), __StackToFlat(&PgCount));
  166.                     if ((rc == NO_ERROR) || (rc == ERROR_NOBLOCK)) {
  167.  
  168.  
  169.                 /*************************************************************/
  170.                 /*** If no data is present, simply set the semaphore       ***/
  171.                 /*************************************************************/
  172.                 if (BufPtr == 0) {
  173.                     *plenDataOut = 0;
  174.                     rc = NO_ERROR;
  175.                 } else {
  176.  
  177.                     /*************************************************************/
  178.                     /*** If the log data is smaller than the requested amount  ***/
  179.                     /*** we copy them all                                      ***/
  180.                     /*************************************************************/
  181.                     if (BufPtr < parms->lenData) {
  182.                         memcpy(pData, BufMsg, BufPtr + 1);
  183.                         *plenDataOut = BufPtr + 1;
  184.                         BufPtr = 0;
  185.                         rc = NO_ERROR;
  186.                     }
  187.                 }
  188.                 /*************************************************************/
  189.                 /*** We set the log semaphore                              ***/
  190.                 /*** ext2-os2.exe will wait on it until some more data is  ***/
  191.                 /*** present                                               ***/
  192.                 /*************************************************************/
  193.                 fsh32_semset(&BufSem);
  194.  
  195.          
  196.              if ((rc2 = DevHlp32_VMUnlock(__StackToFlat(lock_2))) == NO_ERROR) {
  197.                         } else {
  198.                 rc = rc2;
  199.                         }
  200.  
  201.                     }
  202.             if ((rc2 = DevHlp32_VMUnlock(__StackToFlat(lock_1))) == NO_ERROR) {
  203.                     } else {
  204.                 rc = rc2;
  205.                     }
  206.                 }
  207.             }
  208.         }
  209.     } else {
  210.         rc = ERROR_NOT_READY;
  211.     }
  212.     return rc;
  213. }
  214.  
  215. int ext2_os2_bdflush(struct fs32_fsctl_parms *parms) {
  216.     /*
  217.      * We should never return from this call.
  218.      */
  219.     sys_bdflush(0, 0);
  220.  
  221.     return NO_ERROR;    // makes compiler happy
  222. }
  223.  
  224.  
  225.  
  226. int ext2_os2_shrink_cache(struct fs32_fsctl_parms *parms) {
  227.     while(1) {
  228.         if (buffermem)
  229.             shrink_buffers(3);
  230.         DevHlp32_ProcBlock((unsigned long)ext2_os2_shrink_cache, 10000, 1);
  231.     }
  232.     return NO_ERROR; // makes compiler happy
  233. }
  234.  
  235. int ext2_os2_getdata(struct fs32_fsctl_parms *parms) {
  236.     int  rc, rc2;
  237.     char *pData;
  238.     unsigned short *plenDataOut;
  239.     char lock_1[12];
  240.     char lock_2[12];
  241.     unsigned long PgCount;
  242.     struct ext2_os2_data *d;
  243.  
  244.         if ((rc = DevHlp32_VirtToLin(parms->pData, __StackToFlat(&pData))) == NO_ERROR) {
  245.             if ((rc = DevHlp32_VirtToLin(parms->plenDataOut, __StackToFlat(&plenDataOut))) == NO_ERROR) {
  246. //                rc = DevHlp32_VMLock(VMDHL_LONG | VMDHL_VERIFY | VMDHL_WRITE, pData, sizeof(struct ext2_os2_data), (void *)-1, __StackToFlat(lock_1), __StackToFlat(&PgCount));
  247. //                if ((rc == NO_ERROR) || (rc == ERROR_NOBLOCK)) {
  248. //                    rc = DevHlp32_VMLock(VMDHL_LONG | VMDHL_VERIFY | VMDHL_WRITE, plenDataOut, sizeof(short), (void *)-1, __StackToFlat(lock_2), __StackToFlat(&PgCount));
  249. //                    if ((rc == NO_ERROR) || (rc == ERROR_NOBLOCK)) {
  250.  
  251.                     d = (struct ext2_os2_data *)pData;
  252.  
  253.                     /*
  254.                      * Buffers statistics
  255.                      */ 
  256.                     d->b.buffer_mem      = buffermem;
  257.                     d->b.cache_size      = cache_size;
  258.                     d->b.nr_buffer_heads = nr_buffer_heads;
  259.  
  260.                     memcpy(&(d->b.nr_free), nr_free, sizeof(nr_free));
  261.                     memcpy(&(d->b.nr_buffers_type), nr_buffers_type, sizeof(nr_buffers_type));
  262.  
  263.                     /*
  264.                      * I-nodes statistics
  265.                      */ 
  266.                     d->i.nr_inodes      = nr_inodes;
  267.                     d->i.nr_free_inodes = nr_free_inodes;
  268.                     d->i.nr_iget        = nr_iget;
  269.                     d->i.nr_iput        = nr_iput;
  270.  
  271.                     /*
  272.                      * Files statistics
  273.                      */ 
  274.                     d->f.nhfiles     = nr_files;
  275.                     d->f.nfreehfiles = nr_free_files;
  276.                     d->f.nusedhfiles = nr_used_files;
  277.  
  278.                     /*
  279.                      * Swapper statistics
  280.                      */ 
  281.                     d->s.nr_total_pgin  = nr_total_pgin;
  282.                     d->s.nr_total_pgout = nr_total_pgout;
  283.                     d->s.nr_pgin        = nr_pgin;
  284.                     d->s.nr_pgout       = nr_pgout;
  285.                     nr_pgin             = 0;
  286.                     nr_pgout            = 0;
  287.  
  288.                     *plenDataOut = sizeof(struct ext2_os2_data);
  289.  
  290. //             if ((rc2 = DevHlp32_VMUnlock(__StackToFlat(lock_2))) == NO_ERROR) {
  291. //                        } else {
  292. //                rc = rc2;
  293. //                        }
  294.  
  295. //                    }
  296. //            if ((rc2 = DevHlp32_VMUnlock(__StackToFlat(lock_1))) == NO_ERROR) {
  297. //                    } else {
  298. //                rc = rc2;
  299. //                    }
  300. //                }
  301.             }
  302.         }
  303.     return rc;
  304.  
  305. }
  306.  
  307. int ext2_os2_sync(struct fs32_fsctl_parms *parms) {
  308.     int rc;
  309. //    struct vpfsi32 *pvpfsi;
  310. //    struct vpfsd32 *pvpfsd;
  311.     int i;
  312.     struct super_block *sb;
  313.  
  314.         //
  315.         // VFSAPI Library entry point : this is the vfs_sync() routine (standart sync() system call)
  316.         // Input :
  317.         //      pData (ignored)
  318.         //      pParm (ignored)
  319.         // Output :
  320.         //      pData (ignored)
  321.         //      pParm (ignored)
  322.         //
  323.             if (Read_Write) {
  324. #if 0
  325.                 for (i = 0 ; i < NB_MAX_VOLS ; i++) {
  326.                     if (volglobdat.listvol[i].status == VOL_STATUS_MOUNTED) {
  327. //                        fsh32_getvolparm(volglobdat.listvol[i].hVPB, __StackToFlat(&pvpfsi16), __StackToFlat(&pvpfsd16));
  328.                         sb = getvolume(volglobdat.listvol[i].hVPB);
  329.  
  330.                         if (sb) {
  331.                             kernel_printf("Flushing volume 0x%0X", volglobdat.listvol[i].hVPB);
  332.                             sync_buffers(sb->s_dev, 0);
  333.                             sync_inodes(sb->s_dev);
  334.                             sync_buffers(sb->s_dev, 0);
  335.                         }
  336.                     }
  337.                 }
  338. #endif
  339.         sys_sync();
  340.                 rc = NO_ERROR;
  341.             } else {
  342.                 rc = ERROR_WRITE_PROTECT;
  343.             }
  344.     return rc;
  345. }
  346.  
  347. int ext2_os2_stat(struct fs32_fsctl_parms *parms) {
  348.     int  rc, rc2;
  349.     char *pData;
  350.     unsigned short *plenDataOut;
  351.     char lock_1[12];
  352.     char lock_2[12];
  353.     unsigned long PgCount;
  354.     struct ext2_os2_data *d;
  355.     union argdat32 *pArgdat;
  356.     struct super_block *sb;
  357.  
  358.     if (parms->iArgType == FSCTL_ARG_CURDIR) {
  359.     if (parms->lenData  >= sizeof(struct new_stat)) {
  360.         if ((rc = DevHlp32_VirtToLin(parms->pArgdat, __StackToFlat(&pArgdat))) == NO_ERROR) {
  361.         if ((rc = DevHlp32_VirtToLin(parms->pData, __StackToFlat(&pData))) == NO_ERROR) {
  362.             if ((rc = DevHlp32_VirtToLin(parms->plenDataOut, __StackToFlat(&plenDataOut))) == NO_ERROR) {
  363.                 rc = DevHlp32_VMLock(VMDHL_LONG | VMDHL_VERIFY | VMDHL_WRITE, pData, sizeof(struct new_stat), (void *)-1, __StackToFlat(lock_1), __StackToFlat(&PgCount));
  364.                 if ((rc == NO_ERROR) || (rc == ERROR_NOBLOCK)) {
  365.                     rc = DevHlp32_VMLock(VMDHL_LONG | VMDHL_VERIFY | VMDHL_WRITE, plenDataOut, sizeof(short), (void *)-1, __StackToFlat(lock_2), __StackToFlat(&PgCount));
  366.                     if ((rc == NO_ERROR) || (rc == ERROR_NOBLOCK)) {
  367.  
  368.         //
  369.         // VFSAPI Library entry point : this is the vfs_stat() routine (standart stat() system call)
  370.         // Input :
  371.         //         pData must point to a buffer large enough to hold struct vfs_stat
  372.         //      pParm (ignored)
  373.         // Output :
  374.         //         pData contains the struct vfs_stat if success, or garbage if failed
  375.         //      pParm (ignored)
  376.         //
  377.             *plenDataOut = sizeof(struct new_stat);
  378.  
  379.             kernel_printf("FS_FSCTL(EXT2_OS2_STAT) - Path is %s", pArgdat->cd.pPath);
  380.             {
  381.                  struct file       *f;
  382.                  struct new_stat   *s;
  383.                  unsigned long      DOSmode;
  384.                 //
  385.                 // Gets the superblock
  386.                 //
  387.                 sb = getvolume(pArgdat->cd.pcdfsi->cdi_hVPB);
  388.                 DOSmode = (is_case_retensive() ? OPENMODE_DOSBOX : 0);
  389.  
  390.                 if ((f = _open_by_name(sb, pArgdat->cd.pPath, OPENMODE_READONLY | DOSmode)) != NULL) {
  391.  
  392.                 s = (struct new_stat *)pData;
  393.                 memset(s, 0, sizeof(struct new_stat));
  394.                 s->st_dev = f->f_inode->i_dev;
  395.                 s->st_ino = f->f_inode->i_ino;
  396.                 s->st_mode = f->f_inode->i_mode;
  397.                 s->st_nlink = f->f_inode->i_nlink;
  398.                 s->st_uid = f->f_inode->i_uid;
  399.                 s->st_gid = f->f_inode->i_gid;
  400.                 s->st_rdev = f->f_inode->i_rdev;
  401.                 s->st_size = f->f_inode->i_size;
  402. //        if (inode->i_pipe)
  403. //                tmp.st_size = PIPE_SIZE(*inode);
  404.                 s->st_atime = f->f_inode->i_atime;
  405.                 s->st_mtime = f->f_inode->i_mtime;
  406.                 s->st_ctime = f->f_inode->i_ctime;
  407.                 s->st_blocks = f->f_inode->i_blocks;
  408.                 s->st_blksize = f->f_inode->i_blksize;             
  409.                 vfs_close(f);
  410.                 } else {
  411.                     kernel_printf("FS_FSCTL() - path %s not found", pArgdat->cd.pPath);
  412.                     return rc;
  413.                 }
  414.             }
  415.  
  416.  
  417.              if ((rc2 = DevHlp32_VMUnlock(__StackToFlat(lock_2))) == NO_ERROR) {
  418.                         } else {
  419.                 rc = rc2;
  420.                         }
  421.  
  422.                     }
  423.             if ((rc2 = DevHlp32_VMUnlock(__StackToFlat(lock_1))) == NO_ERROR) {
  424.                     } else {
  425.                 rc = rc2;
  426.                     }
  427.                 }
  428.             }
  429.         }
  430.     }
  431.     } else {
  432.         rc = ERROR_BUFFER_OVERFLOW;
  433.     }
  434.     } else {
  435.         rc = ERROR_INVALID_PARAMETER;
  436.     }
  437.     return rc;
  438.  
  439. }
  440.  
  441. int ext2_os2_fstat(struct fs32_fsctl_parms *parms) {
  442.     int  rc, rc2;
  443.     char *pData;
  444.     unsigned short *plenDataOut;
  445.     char lock_1[12];
  446.     char lock_2[12];
  447.     unsigned long PgCount;
  448.     struct ext2_os2_data *d;
  449.     union argdat32 *pArgdat;
  450.     struct super_block *sb;
  451.  
  452.     if (parms->iArgType == FSCTL_ARG_FILEINSTANCE) {
  453.         if (parms->lenData >= sizeof(struct new_stat)) {
  454.  
  455.  
  456.         if ((rc = DevHlp32_VirtToLin(parms->pArgdat, __StackToFlat(&pArgdat))) == NO_ERROR) {
  457.         if ((rc = DevHlp32_VirtToLin(parms->pData, __StackToFlat(&pData))) == NO_ERROR) {
  458.             if ((rc = DevHlp32_VirtToLin(parms->plenDataOut, __StackToFlat(&plenDataOut))) == NO_ERROR) {
  459.                 rc = DevHlp32_VMLock(VMDHL_LONG | VMDHL_VERIFY | VMDHL_WRITE, pData, sizeof(struct new_stat), (void *)-1, __StackToFlat(lock_1), __StackToFlat(&PgCount));
  460.                 if ((rc == NO_ERROR) || (rc == ERROR_NOBLOCK)) {
  461.                     rc = DevHlp32_VMLock(VMDHL_LONG | VMDHL_VERIFY | VMDHL_WRITE, plenDataOut, sizeof(short), (void *)-1, __StackToFlat(lock_2), __StackToFlat(&PgCount));
  462.                     if ((rc == NO_ERROR) || (rc == ERROR_NOBLOCK)) {
  463.  
  464.         //
  465.         // VFSAPI Library entry point : this is the vfs_fstat() routine (standart fstat() system call)
  466.         // Input :
  467.         //         pData must point to a buffer large enough to hold struct vfs_stat
  468.         //      pParm (ignored)
  469.         // Output :
  470.         //         pData contains the struct vfs_stat if success, or garbage if failed
  471.         //      pParm (ignored)
  472.         //
  473.  
  474.             *plenDataOut = sizeof(struct new_stat);
  475.  
  476.             {
  477.                 struct new_stat *s;
  478.                 struct inode    *inode;
  479.  
  480.                 inode = pArgdat->sf.psffsd->f->f_inode;
  481.                 s = (struct new_stat *)pData;
  482.  
  483.                 memset(s, 0, sizeof(struct new_stat));
  484.                 s->st_dev = inode->i_dev;
  485.                 s->st_ino = inode->i_ino;
  486.                 s->st_mode = inode->i_mode;
  487.                 s->st_nlink = inode->i_nlink;
  488.                 s->st_uid = inode->i_uid;
  489.                 s->st_gid = inode->i_gid;
  490.                 s->st_rdev = inode->i_rdev;
  491.                 s->st_size = inode->i_size;
  492. //        if (inode->i_pipe)
  493. //                tmp.st_size = PIPE_SIZE(*inode);
  494.                 s->st_atime = inode->i_atime;
  495.                 s->st_mtime = inode->i_mtime;
  496.                 s->st_ctime = inode->i_ctime;
  497.                 s->st_blocks = inode->i_blocks;
  498.                 s->st_blksize = inode->i_blksize;
  499.             }
  500.             rc = NO_ERROR;
  501.  
  502.  
  503.              if ((rc2 = DevHlp32_VMUnlock(__StackToFlat(lock_2))) == NO_ERROR) {
  504.                         } else {
  505.                 rc = rc2;
  506.                         }
  507.  
  508.                     }
  509.             if ((rc2 = DevHlp32_VMUnlock(__StackToFlat(lock_1))) == NO_ERROR) {
  510.                     } else {
  511.                 rc = rc2;
  512.                     }
  513.                 }
  514.             }
  515.         }
  516.     }
  517.  
  518.         } else {
  519.             rc = ERROR_BUFFER_OVERFLOW;
  520.         }
  521.     } else {
  522.         rc = ERROR_INVALID_PARAMETER;
  523.     }
  524.  
  525. }
  526.  
  527. /*
  528.  * struct fs32_fsctl_parms {
  529.  *     PTR16          plenDataOut;
  530.  *     unsigned short lenData;
  531.  *     PTR16          pData;
  532.  *     PTR16          plenParmOut;
  533.  *     unsigned short lenParm;
  534.  *     PTR16          pParm;
  535.  *     unsigned short func;
  536.  *     unsigned short iArgType;
  537.  *     PTR16          pArgdat;
  538.  * };
  539.  */
  540. int FS32ENTRY fs32_fsctl(struct fs32_fsctl_parms *parms) {
  541.     int             rc;
  542.  
  543.     parms = __StackToFlat(parms);
  544.  
  545.     switch (parms->func) {
  546.         case FSCTL_FUNC_NEW_INFO :
  547.         rc = fsctl_func_new_info(parms);
  548.         break;
  549.         case IFSDBG_OPEN :
  550.         rc = ifsdbg_open(parms);
  551.         break;
  552.     case IFSDBG_CLOSE :
  553.             rc = ifsdbg_close(parms);
  554.         break;
  555.     case IFSDBG_READ :
  556.         rc = ifsdbg_read(parms);
  557.         break;
  558.     case EXT2_OS2_BDFLUSH :
  559.         rc = ext2_os2_bdflush(parms);
  560.         break;
  561.     case EXT2_OS2_SHRINK_CACHE :
  562.         rc = ext2_os2_shrink_cache(parms);
  563.         break;
  564.     case EXT2_OS2_GETDATA :
  565.         rc = ext2_os2_getdata(parms);
  566.         break;
  567.     case EXT2_OS2_SYNC :
  568.         rc = ext2_os2_sync(parms);
  569.         break;
  570.     case EXT2_OS2_STAT :
  571.         rc = ext2_os2_stat(parms);
  572.         break;
  573.     case EXT2_OS2_FSTAT :
  574.         rc = ext2_os2_fstat(parms);
  575.         break;
  576.         default :
  577.         rc = ERROR_NOT_SUPPORTED;
  578.         break;
  579.     }
  580.     return rc;
  581. }
  582.